package com.ruoyi.system.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.domain.MaterialPackege;
import com.ruoyi.system.domain.PwsTable;
import com.ruoyi.system.domain.SapData;
import com.ruoyi.system.domain.vo.PwsAndSapAndRgblVo;
import com.ruoyi.system.domain.vo.SapDataRgblVo;
import com.ruoyi.system.service.IMaterialPackegeService;
import com.ruoyi.system.service.PwsTableService;
import com.ruoyi.system.service.SapDataService;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.RgblMapper;
import com.ruoyi.system.domain.Rgbl;
import com.ruoyi.system.service.IRgblService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 【请填写功能名称】Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-02-13
 */
@Service
@Slf4j
public class RgblServiceImpl extends ServiceImpl<RgblMapper,Rgbl> implements IRgblService
{
    @Autowired
    private RgblMapper rgblMapper;
    @Autowired
    private SapDataService sapDataService;
    @Autowired
    private PwsTableService pwsTableService;
    @Autowired
    IMaterialPackegeService materialPackegeService;

    /**
     * 查询【请填写功能名称】
     * 
     * @param id 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public Rgbl selectRgblById(Long id)
    {
        return rgblMapper.selectRgblById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     * 
     * @param rgbl 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<Rgbl> selectRgblList(Rgbl rgbl,Integer pageNum,Integer pageSize)
    {
        LambdaQueryWrapper<Rgbl> lambdaQueryWrapper =new LambdaQueryWrapper<>();
        if(rgbl.getOrderNo()!=null){
            lambdaQueryWrapper.likeLeft(Rgbl::getOrderNo,rgbl.getOrderNo());
        }
        if(rgbl.getIngreNo()!=null){
            lambdaQueryWrapper.likeLeft(Rgbl::getIngreNo,rgbl.getIngreNo());
        }
        if(rgbl.getIngreName()!=null){
            lambdaQueryWrapper.like(Rgbl::getIngreName,rgbl.getIngreName());
        }
        if(rgbl.getSeq()!=null){
            lambdaQueryWrapper.like(Rgbl::getSeq,rgbl.getSeq());
        }

        return rgblMapper.selectPage(new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNum,pageSize),lambdaQueryWrapper).getRecords();
    }

    @Override
    public Long selectRgblCount(Rgbl rgbl) {
        LambdaQueryWrapper<Rgbl> lambdaQueryWrapper =new LambdaQueryWrapper<>();
        if(rgbl.getOrderNo()!=null){
            lambdaQueryWrapper.likeLeft(Rgbl::getOrderNo,rgbl.getOrderNo());
        }
        if(rgbl.getIngreNo()!=null){
            lambdaQueryWrapper.likeLeft(Rgbl::getIngreNo,rgbl.getIngreNo());
        }
        if(rgbl.getIngreName()!=null){
            lambdaQueryWrapper.like(Rgbl::getIngreName,rgbl.getIngreName());
        }
        if(rgbl.getSeq()!=null){
            lambdaQueryWrapper.like(Rgbl::getSeq,rgbl.getSeq());
        }
        return rgblMapper.selectCount(lambdaQueryWrapper);
    }

    @Override
    public List<Rgbl> selectRgblAll(Rgbl rgbl)
    {
        return rgblMapper.selectRgblList(rgbl);
    }
    /**
     * 新增【请填写功能名称】
     * 
     * @param rgbl 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int insertRgbl(Rgbl rgbl)
    {
        return rgblMapper.insertRgbl(rgbl);
    }

    /**
     * 修改【请填写功能名称】
     * 
     * @param rgbl 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateRgbl(Rgbl rgbl)
    {
        return rgblMapper.updateRgbl(rgbl);
    }

    /**
     * 批量删除【请填写功能名称】
     * 
     * @param ids 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteRgblByIds(Long[] ids)
    {
        return rgblMapper.deleteRgblByIds(ids);
    }

    /**
     * 删除【请填写功能名称】信息
     * 
     * @param id 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteRgblById(Long id)
    {
        return rgblMapper.deleteRgblById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addOrUpdateRgbl(List<Long> ids) {
        try {
            //通过ids查出oderNo数据
            List<String> orderNos = sapDataService.getOrderNos(ids);
            //通过orderNos将rgbl中act_weight为空的数据删除
            List<Rgbl> rgblActWeightIsNUllList = this.selectRgblActWeightIsNUllByOrderNos(orderNos);
            Set<Long> rgblIds = rgblActWeightIsNUllList.stream().map(Rgbl::getId).collect(Collectors.toSet());
            if (rgblIds.size() > 0) {
                this.deleteRgblActWeightIsNUllByIds(rgblIds);
            }
            //通过orderNos将rgbl中act_weight>0的数据标记为1
            List<Rgbl> rgblActWeightList = this.selectRgblActWeightByOrderNos(orderNos);
            Set<Long> rgblIds1 = rgblActWeightList.stream().map(Rgbl::getId).collect(Collectors.toSet());
            if (rgblIds1.size() > 0) {
                this.updateRgblStatusByOrderNos(rgblIds1);
            }
            //通过ids查出sapdata数据
            List<SapData> sapDataList = sapDataService.selectByIds(ids);
            //将sapdata数据映射为rgbl数据
            List<Rgbl> rgblList = sapDataList.stream().map(this::sapDateToRgbl).collect(Collectors.toList());
            //将rgbl数据插入rgbl表中
            saveBatch(rgblList);
        } catch (Exception e) {
            log.error("数据插入rgbl表异常:{}",e);
            return false;
        }

        return true;
    }

    @Override
    public List<PwsAndSapAndRgblVo> selectPwsAndSapAndRgblVoByIds(List<Long> ids) {
        List<PwsAndSapAndRgblVo> pwsAndSapAndRgblVos = new ArrayList<>();
        //通过ids查出sapData数据
        List<SapDataRgblVo> SapDataRgblVoList = sapDataService.selectByIdsVo(ids);
        //将sapdate通过单号分类
        Map<String,List<SapDataRgblVo>> sapDataMap = new HashMap<>();
        Set<String> orderNosSet = new HashSet<>();
        for (SapDataRgblVo sapDataRgblVo : SapDataRgblVoList) {
            int oldLen=orderNosSet.size();
            orderNosSet.add(sapDataRgblVo.getOrderNo());
            int newLen=orderNosSet.size();
            if(oldLen==newLen){
                sapDataMap.get(sapDataRgblVo.getOrderNo()).add(sapDataRgblVo);
            }else{
                sapDataMap.put(sapDataRgblVo.getOrderNo(),new ArrayList<>());
                sapDataMap.get(sapDataRgblVo.getOrderNo()).add(sapDataRgblVo);
            }
        }
        //遍历sapDataMap
        for (Map.Entry<String, List<SapDataRgblVo>> entry : sapDataMap.entrySet()) {
            PwsAndSapAndRgblVo pwsAndSapAndRgblVo = new PwsAndSapAndRgblVo();
            //获取pws数据
            PwsTable pwsTable = pwsTableService.getPwsTableByOrderNo(entry.getKey());
            pwsAndSapAndRgblVo.setPwsTable(pwsTable);
            pwsAndSapAndRgblVo.setSapDataRgblVoList(entry.getValue());
            pwsAndSapAndRgblVos.add(pwsAndSapAndRgblVo);
        }
        return pwsAndSapAndRgblVos;
    }

    private Rgbl sapDateToRgbl(SapData sapData) {
        Rgbl rgbl = new Rgbl();
        rgbl.setOrderNo(sapData.getOrderNo());
        rgbl.setIngreNo(sapData.getIngreNo());
        rgbl.setIngreName(sapData.getIngreDesc());
        rgbl.setSeq(sapData.getStep());
        rgbl.setSetWght(sapData.getQty());
        rgbl.setOperation(sapData.getOperation());
        if(StringUtils.isNotBlank(sapData.getIngreNo())&&StringUtils.isNotBlank(sapData.getBatch())){
            MaterialPackege materialPackege = materialPackegeService.selectMaterialPackegeByIngreNoAndTag(sapData.getIngreNo(),sapData.getBatch().substring(0,3));
            rgbl.setBzWght(materialPackege.getCounter());
        }
        if(rgbl.getSetWght()!=null&&rgbl.getBzWght()!=null){
            // 先计算商（向下取整）
            BigDecimal quotient = rgbl.getSetWght().divide(rgbl.getBzWght(), 0, RoundingMode.DOWN);
            // 然后用被除数减去商与除数的乘积得到余数
            BigDecimal remainder = rgbl.getSetWght().subtract(quotient.multiply(rgbl.getBzWght()));
            rgbl.setRemnant(remainder);
        }
        try {
            rgbl.setActWght(new BigDecimal(sapData.getActualUsage()));
        }catch (Exception e){
          log.error("数据{}转换类型异常:{}",sapData.getActualUsage(),e);
        }
        PwsTable pwsTable = pwsTableService.getPwsTableByOrderNo(sapData.getOrderNo());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        try {
            rgbl.setDate(pwsTable.getOrderStartDate().format(formatter));
        }catch (Exception e){
            log.error("数据{}转换类型异常:{}",pwsTable.getOrderStartDate(),e);
        }


        rgbl.setBatchNo(sapData.getBatch());
        rgbl.setCheck1(sapData.getCheck1());
        rgbl.setCheck2(sapData.getCheck2());
        rgbl.setIsDel(0);
        return rgbl;
    }
    public boolean updateRgblStatusByOrderNos(Set<Long> orderNos) {
        LambdaUpdateWrapper<Rgbl> wrapper = new LambdaUpdateWrapper<>();
        wrapper.in(Rgbl::getOrderNo,orderNos);
        wrapper.isNotNull(Rgbl::getActWght);
        wrapper.set(Rgbl::getIsDel,1);
        return update(wrapper);
    }
    public int deleteRgblActWeightIsNUllByIds(Set<Long> ids) {
        LambdaQueryWrapper<Rgbl> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Rgbl::getId,ids);
        return baseMapper.delete(wrapper);
    }
    public List<Rgbl>selectRgblActWeightIsNUllByOrderNos(List<String> orderNos) {
        LambdaQueryWrapper<Rgbl> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Rgbl::getOrderNo,orderNos);
        wrapper.and(w -> w.isNull(Rgbl::getActWght).or().eq(Rgbl::getActWght, 0));
        wrapper.eq(Rgbl::getIsDel, 0); // is_del = 0
        return baseMapper.selectList(wrapper);
    }
    public List<Rgbl>selectRgblActWeightByOrderNos(List<String> orderNos) {
        LambdaQueryWrapper<Rgbl> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Rgbl::getOrderNo,orderNos);
        wrapper.gt(Rgbl::getActWght,0);
        wrapper.eq(Rgbl::getIsDel,0);
        return baseMapper.selectList(wrapper);
    }
}
